#include "GroupModel.hpp"
#include "db.h"
#include <assert.h>

// 创建组
bool GroupModel::createGroup(int userid, Group &group)
{
    char buffer[1024];
    int n = sprintf(buffer, "insert into AllGroup (groupname,groupdesc)values ('%s','%s')",
                    group.getGroupname().c_str(), group.getGroupdesc().c_str());

    assert(n != 0);
    (void)n;
    // 这有大bug啊，咱们根本就不知道群的id，id是后来生成的
    // char buffer2[1024];
    // std::string role = "owner";
    // n = sprintf(buffer2, "insert into GroupUser (group_id,user_id,grouprole)values(%d,%d,'%s')",
    //             group.getId(), userid, role.c_str());

    MySQL sql;
    if (sql.connect())
    {
        mysql_set_character_set(sql.getConnection(), "utf8mb4");

        if (sql.update(buffer))
        {
            // 因为group是自增主键，所以这里才传引用，然后“倒反天罡”的先使用后定义
            group.setId(mysql_insert_id(sql.getConnection()));
            return true;
        }
    }

    return false;
}

// 加入组成为普通组员
bool GroupModel::joinGroup(int userid, int groupid, std::string role)
{
    char buffer[1024];

    // 注意了这里缺少了一步，先得查出这个组存在，然后再让插入
    int n = sprintf(buffer, "insert into GroupUser (group_id,user_id,grouprole)values(%d,%d,'%s')",
                    groupid, userid, role.c_str());

    assert(n != 0);
    (void)n;

    MySQL sql;
    if (sql.connect())
    {
        mysql_set_character_set(sql.getConnection(), "utf8mb4");

        if (sql.update(buffer))
            return true;
    }
    return false;
}

// 查询自己所有所在的组信息
std::vector<Group> GroupModel::queryGroup(int userid)
{
    // 这些信息也是用户上线的时候给他，让他知道自己在哪个组里面
    char buffer[1024];
    int n = sprintf(buffer, "select  t1.id,t1.groupname,t1.groupdesc from AllGroup as t1 inner join \
      GroupUser as t2 on t1.id = t2.group_id where t2.user_id = %d;",
                    userid);

    (void)n;
    assert(n != 0);

    std::vector<Group> ret;

    MySQL sql;
    if (sql.connect())
    {
        mysql_set_character_set(sql.getConnection(), "utf8mb4");
        MYSQL_RES *res = sql.query(buffer);

        if (res != nullptr)
        {
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res)) != nullptr)
            {
                Group group;
                group.setId(atoi(row[0]));
                group.setGroupname(row[1]);
                group.setGroupdesc(row[2]);

                ret.push_back(group);
            }
            return ret;
        }
        mysql_free_result(res);
    }
    return ret;
}

// 查询自己某个所在组的所有成员信息
// 注意了首先用户得先在这个组，然后才能查询这个组的成员信息
std::vector<GroupUser> GroupModel::queryGroupuser(int userid, int groupid)
{
    std::vector<GroupUser> ret;
    if (!isInGroup(userid, groupid))
        return ret;

    char buffer[1024];
    int n = sprintf(buffer, "select t1.id,t1.name,t1.state,t2.grouprole from User as t1 \
     inner join GroupUser t2 on t1.id = t2.user_id  where t2.group_id = %d and t2.user_id != %d",
                    groupid, userid);

    assert(n != 0);
    (void)n;

    MySQL sql;
    if (sql.connect())
    {
        mysql_set_character_set(sql.getConnection(), "utf8mb4");
        MYSQL_RES *res = sql.query(buffer);

        if (res != nullptr)
        {
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res)) != nullptr)
            {
                GroupUser crew;
                crew.setId(atoi(row[0]));
                crew.setName(row[1]);
                crew.setState(row[2]);
                crew.setRole(row[3]);

                ret.push_back(crew);
            }
        }
        mysql_free_result(res);
        return ret;
    }
    return ret;
}

// 这是确认用户在这个组里的关键信息
bool GroupModel::isInGroup(int userid, int groupid)
{
    // 先把自己所有所在组的信息查询一下
    std::vector<Group> mygroup = this->queryGroup(userid);

    // 比对是否在groupid组中  (注意了 ： 如果查询查的很平凡，可以考虑用unordered_map存储数据以优化查询效率)
    for (auto &e : mygroup)
    {
        if (e.getId() == groupid)
            return true;
    }

    return false;
}

bool GroupModel::changeRole(int userid, int groupid, int targetid, std::string newrole)
{
    // 要修改别人的权限,先确认双方都在群聊里面
    if (isInGroup(userid, groupid) && isInGroup(groupid, targetid))
    {
        std::string myrole = queryRole(userid, groupid);
        if (myrole != "owner")
            return false;

        // 现在可以修改被修改成员的权限了
        char buffer[1024];
        int n = sprintf(buffer, "update GroupUser set grouprole = '%s' \
        where group_id = %d and user_id = %d",
                        newrole, groupid, targetid);

        MySQL sql;
        if(sql.connect())
            if(sql.update(buffer)) return true;
    }

    return false;
}

std::string GroupModel::queryRole(int userid, int groupid)
{
    std::string ret;

    if (!isInGroup(userid, groupid))
        return ret;

    char buffer[1024];
    int n = sprintf(buffer, "select grouprole from GroupUser \
    where group_id = %d and user_id = %d",
                    groupid, userid);

    assert(n != 0);
    (void)n;

    MySQL sql;
    if (sql.connect())
    {
        mysql_set_character_set(sql.getConnection(), "utf8mb4");
        MYSQL_RES *res = sql.query(buffer);

        MYSQL_ROW row = mysql_fetch_row(res);
        ret = row[0];

        mysql_free_result(res);
    }
    return ret;
}